package com.fanrui.code.gate.core;

import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;

import com.fanrui.code.gate.client.GameServerClient;
import com.fanrui.code.gate.client.OtherServerClient;
import com.fanrui.code.util.CommandsUtil;
import com.fanrui.code.util.logger.Stdout;
import com.fanrui.proto.cmd.CmdWrapper;
import com.fanrui.proto.cmd.CmdWrapper.CmdType;
import com.fanrui.proto.cmd.ServerCmdWrapper;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.util.AttributeKey;

/**
 * 玩家id与Channel 的封装类
 * 实现玩家id与Channel的映射
 * @author xl
 * */
public class PlayerSession {
 public	static Set<CmdType> filterList = new HashSet<CmdType>();
	static{
		filterList.add(CmdType.ReqHeart);
		filterList.add(CmdType.ResHeart);
	}
	
	// 在channel上保存playerId（主要目的可以通过channel找到session）
	private static AttributeKey<Long> playerIdKey = AttributeKey.valueOf("playerId");
	/**
	 * ip
	 * */
	private String ip;
	// 最后一次通讯时间(用于超时断开Session)
	private long lastCommunicationTime;
	// 客户端链接
	private Channel channel;
	// 上一次使用过的服务器信息
	private OtherServerClient lastUesdServer;
	
	///正在使用的服务器  一个客户端在正常情况下只使用同一个服务器
	private OtherServerClient currentServer;
	
	public PlayerSession(Long playerId,Channel channel) {
		this.channel = channel;
		this.channel.attr(playerIdKey).set(playerId);
		ip = ((InetSocketAddress)channel.remoteAddress()).getAddress().getHostAddress();
		refreshLastCommunicationTime();
		
	}
	public Long getPlayerId() {
		return getPlayerId(this.channel);
	}
	/**
	 * 刷新最后一次通讯的时间
	 * */
	public void refreshLastCommunicationTime() {
		this.lastCommunicationTime = System.currentTimeMillis();
	}
	public boolean isTimeouted(int timeoutTime) {
		return System.currentTimeMillis() > this.lastCommunicationTime + timeoutTime;
	}
	
	/**
	 * 判断这个Sender的channel是不是同一个
	 * 
	 * @param channel
	 * @return
	 */
	public boolean isSameSocket(Channel channel) {
		return this.channel.compareTo(channel) == 0;
	}
	/**
	 * 关闭连接
	 * */
	public ChannelFuture close() {
		return this.channel.close();
	}
	
	/**
	 * 通过连接对象获取玩家id
	 * */
	public static Long getPlayerId(Channel channel) {
		return channel.attr(playerIdKey).get();
	}
	
	public void send(CmdWrapper cmdWrapper) {
		if(!filterList.contains(cmdWrapper.getCmdType())){
			Stdout.GET().info("向玩家{}发送消息：{}",getPlayerId(),CommandsUtil.toString(cmdWrapper));
		}
		if(this.channel.isActive()){
			this.channel.writeAndFlush(cmdWrapper);
		}
	}
	
	public OtherServerClient getLastUesdServer() {
		return lastUesdServer;
	}
	
	public void setLastUesdServer(OtherServerClient lastUesdServer) {
		this.lastUesdServer = lastUesdServer;
	}
	
	public OtherServerClient getCurrentServer() {
		return currentServer;
	}
	
	public void setCurrentServer(OtherServerClient currentServer) {
		this.currentServer = currentServer;
	}
	
	/**
	 * 
	 * 发送request
	 * 
	 * @param listener
	 * @param methodName
	 * @param args
	 * @return
	 * @throws InterruptedException
	 */
	public void sendRequest(ServerCmdWrapper msg) {
		GameServerClient.getInstance().sendRequest(msg);
	}
	
	/**
	 * 记录日志
	 * */
	public String getIp() {
		return ip;
	}
	
}

